// jsencrypt.js
import JsEncrypt from 'jsencrypt'
import * as Base64 from 'js-base64'

class JsEncryptNew extends JsEncrypt {
  constructor() {
    super()
    this.b64map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    this.b64pad = '='
    this.BI_RM = '0123456789abcdefghijklmnopqrstuvwxyz'
  }

  int2char = (n) => {
    return this.BI_RM.charAt(n)
  }

  b64tohex = function (s) {
    let ret = ''
    let i
    let k = 0 // b64 state, 0-3
    let slop = 0
    for (i = 0; i < s.length; ++i) {
      if (s.charAt(i) === this.b64pad) {
        break
      }
      const v = this.b64map.indexOf(s.charAt(i))
      if (v < 0) {
        continue
      }
      if (k === 0) {
        ret += this.int2char(v >> 2)
        slop = v & 3
        k = 1
      }
      else if (k === 1) {
        ret += this.int2char((slop << 2) | (v >> 4))
        slop = v & 0xF
        k = 2
      }
      else if (k === 2) {
        ret += this.int2char(slop)
        ret += this.int2char(v >> 2)
        slop = v & 3
        k = 3
      }
      else {
        ret += this.int2char((slop << 2) | (v >> 4))
        ret += this.int2char(v & 0xF)
        k = 0
      }
    }
    if (k === 1) {
      ret += this.int2char(slop << 2)
    }
    return ret
  }

  hex2b64 = function (h) {
    let i
    let c
    let ret = ''
    for (i = 0; i + 3 <= h.length; i += 3) {
      c = parseInt(h.substring(i, i + 3), 16)
      ret += this.b64map.charAt(c >> 6) + this.b64map.charAt(c & 63)
    }
    if (i + 1 === h.length) {
      c = parseInt(h.substring(i, i + 1), 16)
      ret += this.b64map.charAt(c << 2)
    }
    else if (i + 2 === h.length) {
      c = parseInt(h.substring(i, i + 2), 16)
      ret += this.b64map.charAt(c >> 2) + this.b64map.charAt((c & 3) << 4)
    }
    while ((ret.length & 3) > 0) {
      ret += this.b64pad
    }
    return ret
  }

  // 分段加密
  encryptLong = function (string) {
    const k = this.getKey()
    // var maxLength = (((k.n.bitLength() + 7) >> 3) - 11);//117
    try {
      // var lt = '';
      let ct = ''
      // RSA每次加密117bytes，需要辅助方法判断字符串截取位置
      // 1.获取字符串截取点
      const bytes = []
      bytes.push(0)
      let byteNo = 0
      let len, c
      len = string.length
      let temp = 0
      for (let i = 0; i < len; i++) {
        c = string.charCodeAt(i)
        if (c >= 0x010000 && c <= 0x10FFFF) {
          byteNo += 4
        }
        else if (c >= 0x000800 && c <= 0x00FFFF) {
          byteNo += 3
        }
        else if (c >= 0x000080 && c <= 0x0007FF) {
          byteNo += 2
        }
        else {
          byteNo += 1
        }
        if ((byteNo % 117) >= 114 || (byteNo % 117) === 0) {
          if (byteNo - temp >= 114) {
            bytes.push(i)
            temp = byteNo
          }
        }
      }
      // 2.截取字符串并分段加密
      if (bytes.length > 1) {
        for (let i = 0; i < bytes.length - 1; i++) {
          var str
          if (i === 0) {
            str = string.substring(0, bytes[i + 1] + 1)
          }
          else {
            str = string.substring(bytes[i] + 1, bytes[i + 1] + 1)
          }
          const t1 = k.encrypt(str)
          ct += t1
        }

        if (bytes[bytes.length - 1] !== string.length - 1) {
          const lastStr = string.substring(bytes[bytes.length - 1] + 1)
          ct += k.encrypt(lastStr)
          // debugger;
        }
        return this.hex2b64(ct)
      }
      const t = k.encrypt(string)
      const y = this.hex2b64(t)
      return y
    }
    catch (ex) {
      return false
    }
  }

  // 分段解密长字符串
  decryptLong = function (text) {
    // Return the decrypted string.
    const k = this.getKey()
    const maxLength = ((k.n.bitLength() + 7) >> 3)
    try {
      const str = this.b64tohex(text)
      // var b=hex2Bytes(str);

      const inputLen = str.length

      let ct = ''

      if (inputLen > maxLength) {
        const lt = str.match(/.{1,256}/g)
        lt.forEach((entry) => {
          const t1 = k.decrypt(entry)
          ct += t1
        })
        return ct
      }
      const y = k.decrypt(this.b64tohex(text))
      return y
    }
    catch (ex) {
      return false
    }
  }
}

const publicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4Z6tfG2riN8FbPCGM9uQ461hO
wiWBT2pZN7qk9R14ub7DN1bBm2M+h9OtrXy/T0HwA28eXcvTUI9G4uDW10DQ4Q8D
khUH+QEapRPLm+E/5Y5FLXlP6QU+wRhjKmzZYBmfdr8o6sS4cBBtlmPtb0hpwbho
lIqjK+r4GgMz/VR3EwIDAQAB
-----END PUBLIC KEY-----`
export function RSAencrypt(str, key = publicKey) {
  const ENCRYPT = new JsEncryptNew()
  ENCRYPT.setPublicKey(key)
  return ENCRYPT.encryptLong(Base64.encode(str).toString())
}

// 这里的rsa加解密是使用两套密钥,这里的私钥是解密登录传值的,

const privateKey = `-----BEGIN PRIVATE KEY-----
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALd9ORpVr8dsxY0S
V+cXvJDe2XhIXlgkVICkv5V2D9/XOhuT8t9Qwg4mtCQeBq62Ff37qgnaUg5spvG0
pFY3oqeJ78EOtoX4rG8B6GqEEgDtVRVFAyh7uMNoKxSd561SVEjWvmjf9zzjq2fz
L43133birWddwzpoIb/K+TPoK03nAgMBAAECgYBzhv1gDlk5V8veMZF05+YK1LTZ
3b7BAkbOJGyXvxjpl4p3eKRvZFp6LHY5U0pj0DNykXSS9Ym6mUBXaKQbwLXAcvud
zazcZNLiax6xHMsp2BOzxCjafX8SoFXo+ySG11HI9HIDVuL/qzP4+uE3+EJrWytM
DFfZoMHr3zvacJT+YQJBAOqPqoFWBGiTngsoMXkZGZP46nZCsNSxd2iYKeFHrl9r
2/WK2SSLI1hm34nRjIwxysE+Y7ELnFFTsWRUZud+gtcCQQDIQo7RKK5e8kAC2SMW
+CSR1ryK/JsgF4hBm2iMrsYwPnflkb25STRWmnCh1fNO0xqox0Kcga3hht9lztK+
tDtxAkEAvCibAj1aM/mWoiSP6zCzT/wxOMSuzS+/New6TDkQLAN94y6KmcHzjIqZ
bxjlweB/YR0HI5LIxoR4nJ8IHVNi6QJBAMX33h1wnOgpjRQDuceUKPqvEJZJX8Ta
3o0U58bjY/L/XiFo8OhBMOdIJ34k9jD/SgR9byEupUkkvqVzTyzNGVECQQC0RjG8
dw0vO8D1DK90ZCd3In9sdBZdVneNlJHKZz+3hukeJUksKkoTl4UmxfenuaRJalIi
4dx9WCXJQspR2wl0
-----END PRIVATE KEY-----`
export function RSAdncrypt(str, key = privateKey) {
  const ENCRYPT = new JsEncryptNew()
  ENCRYPT.setPrivateKey(key)
  return Base64.decode(ENCRYPT.decryptLong(str.toString()))
}
